import axios, { AxiosResponse, AxiosPromise } from 'axios'
import { WebResponse } from '../interface'
import { getTokenKey, getToken } from './cookie'
import { isNotEmpty } from './validate'
import { showMessage, showAlert } from './element/message'
import { userModule } from '../store/modules/user'

const errorResponseFlag = '_error-response_'
const tokenMessage = new Map<number, string>([
  [ 10001, '令牌非法' ],
  [ 10002, '令牌过期' ],
  [ 10003, '令牌失效' ]
])

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  headers: { 'Content-Type': 'application/json;charset=UTF-8' },
  timeout: 5000
})

// request interceptor
service.interceptors.request.use(
  (config) => {
    const token = getToken()
    if (isNotEmpty(token)) {
      // 为请求绑定 token
      config.headers[getTokenKey()] = token
    }
    return config
  },
  (error) => {
    console.error(error)
    showMessage(error, 'error')
    return errorResponseFlag
  }
)

// response interceptor
service.interceptors.response.use(
  (response) => {
    const data: WebResponse = response.data
    if (isNotEmpty(data)) {
      const code = data.code
      const messages = data.messages || ''
      const responseBody = data.responseBody
      if (code === 10001 || code === 10002 || code === 10003) {
        showAlert(tokenMessage.get(code) || '', 'warning', '登出').then(() => {
          userModule.clear()
          location.reload() // 刷新页面（整个页面重新实例化），由于令牌被清除，路由重定向到登录页
        })
        response.data = errorResponseFlag // 重新指定 data 的值
        return response
      } else if (code === 200) {
        response.data = responseBody // 重新指定 data 的值
        return response
      } else if (code === 251) {
        showMessage(messages, 'error')
        response.data = responseBody // 重新指定 data 的值
        return response
      } else if (code === 500) {
        showMessage(messages, 'error')
        response.data = errorResponseFlag // 重新指定 data 的值
        return response
      } else {
        return response
      }
    } else {
      return response
    }
  },
  (error) => {
    console.error(error)
    showMessage(error, 'error')
    return errorResponseFlag
  }
)

export default service

/**
 * 生成一个空的 AxiosResponse
 * @param data AxiosResponse.data
 * @return 空的 AxiosResponse
 */
export const emptyResponse = (data: any) => {
  const response: AxiosResponse<any> = {
    data,
    status: 200,
    statusText: '',
    headers: {},
    config: {}
  }
  return response
}

/**
 * 是否为有效的响应
 * @param response axios 响应
 * @return 布尔值 [true 有效 | false 无效]
 */
export const validResponse = (response: AxiosResponse<any>) => {
  return isNotEmpty(response) && response.data !== errorResponseFlag
}

/**
 * 串行执行多个请求
 * @param requests 响应集
 * @return Promise，通过 Promise.then(datas => {}) 处理结果集
 */
export function serial(requests: (() => AxiosPromise<any>)[]) {
  const datas: any = []
  let promise = Promise.resolve()
  if (isNotEmpty(requests)) {
    requests.forEach((request) => {
      promise = promise.then(request).then(data => {
        datas.push(data)
        return datas
      })
    })
  }
  return promise
}

/**
 * 并行执行多个请求
 * @param requests 响应集
 * @return Promise 集
 */
export const parallel = (requests: (() => AxiosPromise<any>)[]) => {
  return Promise.all(requests)
}
